package cn.caplike.demo.nio._2021.buffer;

import java.nio.ByteBuffer;

/**
 * <dl>
 *     <dd><b>l</b>imit</dd>
 *     <dd><b>p</b>osition: 即将要读或者写的位置.</dd>
 *     <dd><b>c</b>apacity</dd>
 * </dl>
 *
 * @author LiKe
 * @version 1.0.0
 * @date 2022-01-10 12:48
 * @see java.nio.Buffer
 */
public class HeapByteBufferDemo {

    public static void main(String[] args) {
        getAndPut();
        System.out.println("---");
        slice();
        System.out.println("---");
        readonly();
    }

    /**
     * 类型化的 buffer 的 put 和 get.
     */
    private static void getAndPut() {
        ByteBuffer buffer = ByteBuffer.allocate(64); // p0 l64 c64

        buffer.putInt(15);
        buffer.putLong(500000000L);
        buffer.putDouble(13.123456);
        buffer.putChar('你');
        buffer.putShort((short) 2);
        buffer.putChar('我');

        buffer.flip(); // p0 l64->l?

        System.out.println(buffer.getInt());
        System.out.println(buffer.getLong());
        System.out.println(buffer.getDouble());
        System.out.println(buffer.getChar());
        System.out.println(buffer.getShort());
        System.out.println(buffer.getChar());
    }

    /**
     * Slice Buffer
     */
    private static void slice() {
        ByteBuffer buffer = ByteBuffer.allocate(10);

        for (int i = 0; i < buffer.capacity(); ++i) {
            buffer.put((byte) i);
        }

        buffer.position(2);
        buffer.limit(6);

        ByteBuffer sliceBuffer = buffer.slice(); // 底层数据就是一份
        for (int i = 0; i < sliceBuffer.capacity(); ++i) {
            byte b = sliceBuffer.get(i);
            b *= 2;
            sliceBuffer.put(i, b);
        }

        buffer.position(0);
        buffer.limit(buffer.capacity());
        while (buffer.hasRemaining()) {
            System.out.println(buffer.get());
        }
    }

    private static void readonly() {
        ByteBuffer buffer = ByteBuffer.allocate(10);
        System.out.println(buffer.getClass());

        for (int i = 0; i < buffer.capacity(); ++i) {
            buffer.put((byte) i);
        }

        final ByteBuffer readOnlyBuffer = buffer.asReadOnlyBuffer();
        System.out.println(readOnlyBuffer.getClass());

        readOnlyBuffer.position(0);
        readOnlyBuffer.put((byte) 2);
    }
}
